package com.haohan.cloud.scm.opc.utils;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.haohan.cloud.scm.api.aftersales.entity.ReturnOrder;
import com.haohan.cloud.scm.api.aftersales.entity.ReturnOrderDetail;
import com.haohan.cloud.scm.api.aftersales.feign.ReturnOrderDetailFeignService;
import com.haohan.cloud.scm.api.aftersales.feign.ReturnOrderFeignService;
import com.haohan.cloud.scm.api.aftersales.req.ReturnOrderDetailReq;
import com.haohan.cloud.scm.api.aftersales.req.ReturnOrderReq;
import com.haohan.cloud.scm.api.bill.dto.OrderInfoDTO;
import com.haohan.cloud.scm.api.constant.ScmCacheNameConstant;
import com.haohan.cloud.scm.api.constant.enums.bill.OrderTypeEnum;
import com.haohan.cloud.scm.api.crm.dto.CustomerMerchantDTO;
import com.haohan.cloud.scm.api.crm.entity.SalesOrder;
import com.haohan.cloud.scm.api.crm.feign.CustomerMerchantRelationFeignService;
import com.haohan.cloud.scm.api.crm.feign.SalesOrderFeignService;
import com.haohan.cloud.scm.api.crm.req.SalesOrderReq;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.feign.GoodsModelFeignService;
import com.haohan.cloud.scm.api.manage.dto.PhotoGroupDTO;
import com.haohan.cloud.scm.api.manage.entity.PhotoGallery;
import com.haohan.cloud.scm.api.manage.entity.PhotoGroupManage;
import com.haohan.cloud.scm.api.manage.feign.PhotoGroupManageFeignService;
import com.haohan.cloud.scm.api.opc.entity.SummaryOrder;
import com.haohan.cloud.scm.api.product.entity.ProductInfo;
import com.haohan.cloud.scm.api.product.feign.ProductInfoFeignService;
import com.haohan.cloud.scm.api.product.req.QueryGoodsStorageReq;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseOrder;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseOrderDetail;
import com.haohan.cloud.scm.api.purchase.feign.PurchaseOrderDetailFeignService;
import com.haohan.cloud.scm.api.purchase.feign.PurchaseOrderFeignService;
import com.haohan.cloud.scm.api.purchase.req.AddPurchaseOrderReq;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrder;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrderDetail;
import com.haohan.cloud.scm.api.saleb.entity.Buyer;
import com.haohan.cloud.scm.api.saleb.feign.BuyOrderDetailFeignService;
import com.haohan.cloud.scm.api.saleb.feign.BuyOrderFeignService;
import com.haohan.cloud.scm.api.saleb.feign.BuyerFeignService;
import com.haohan.cloud.scm.api.saleb.req.BuyOrderDetailReq;
import com.haohan.cloud.scm.api.saleb.req.BuyOrderReq;
import com.haohan.cloud.scm.api.saleb.req.BuyerReq;
import com.haohan.cloud.scm.api.supply.entity.OfferOrder;
import com.haohan.cloud.scm.api.supply.entity.Supplier;
import com.haohan.cloud.scm.api.supply.entity.SupplyOrder;
import com.haohan.cloud.scm.api.supply.feign.OfferOrderFeignService;
import com.haohan.cloud.scm.api.supply.feign.SupplierFeignService;
import com.haohan.cloud.scm.api.supply.feign.SupplyOrderFeignService;
import com.haohan.cloud.scm.api.supply.req.OfferOrderReq;
import com.haohan.cloud.scm.api.supply.req.SupplierReq;
import com.haohan.cloud.scm.api.supply.req.SupplyOrderReq;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.haohan.cloud.scm.opc.service.SummaryOrderService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author cx
 * @date 2019/6/19
 */
@Component
@AllArgsConstructor
public class ScmOpcUtils {
    private final GoodsModelFeignService goodsModelFeignService;
    private final SummaryOrderService summaryOrderService;
    private final ProductInfoFeignService productInfoFeignService;
    private final PurchaseOrderDetailFeignService purchaseOrderDetailFeignService;
    private final PurchaseOrderFeignService purchaseOrderFeignService;

    private final SupplierFeignService supplierFeignService;
    private final OfferOrderFeignService offerOrderFeignService;
    private final SupplyOrderFeignService supplyOrderFeignService;

    private final BuyerFeignService buyerFeignService;
    private final BuyOrderFeignService buyOrderFeignService;
    private final BuyOrderDetailFeignService buyOrderDetailFeignService;

    private final ReturnOrderFeignService returnOrderFeignService;
    private final ReturnOrderDetailFeignService returnOrderDetailFeignService;
    private final PhotoGroupManageFeignService photoGroupManageFeignService;

    private final SalesOrderFeignService salesOrderFeignService;
    private final CustomerMerchantRelationFeignService customerMerchantRelationFeignService;

    /**
     * 商品规格信息
     *
     * @param goodsModelId
     * @return
     */
    public GoodsModelDTO fetchGoodsModel(String goodsModelId) {
        R infoById = goodsModelFeignService.getInfoById(goodsModelId, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(infoById)) {
            throw new ErrorDataException("商品规格信息有误");
        }
        return BeanUtil.toBean(infoById.getData(), GoodsModelDTO.class);
    }

    /**
     * 查询summaryOrder
     *
     * @param pmId
     * @param summaryOrderId
     * @return
     */
    public SummaryOrder querySummaryOrder(String pmId, String summaryOrderId) {
        SummaryOrder queryOrder = new SummaryOrder();
        queryOrder.setPmId(pmId);
        queryOrder.setSummaryOrderId(summaryOrderId);
        SummaryOrder order = summaryOrderService.getOne(Wrappers.query(queryOrder));
        if (null == order) {
            throw new EmptyDataException();
        }
        return order;
    }

    /**
     * 查询商品库存
     *
     * @param pmId
     * @param goodsModelId
     * @return
     */
    public ProductInfo queryGoodsStorage(String pmId, String goodsModelId) {
        QueryGoodsStorageReq req = new QueryGoodsStorageReq();
        req.setPmId(pmId);
        req.setGoodsModelId(goodsModelId);
        R r = productInfoFeignService.queryGoodsStorage(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()) {
            throw new ErrorDataException("查询商品库存有误");
        }
        return BeanUtil.toBean(r.getData(), ProductInfo.class);
    }


    /**
     * 根据汇总单生成采购明细
     *
     * @param summaryOrder id 或 summaryOrderId 唯一标识汇总单
     * @return
     */
    public PurchaseOrderDetail addPurchaseOrderDetail(SummaryOrder summaryOrder) {
        R r = purchaseOrderDetailFeignService.addPurchaseOrderDetail(summaryOrder, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()) {
            throw new ErrorDataException(r.getMsg());
        }
        return BeanUtil.toBean(r.getData(), PurchaseOrderDetail.class);
    }

    /**
     * 根据purchaseOrderDetailSn添加PurchaseOrde
     *
     * @param req 采购单明细sn列表
     * @return
     */
    public PurchaseOrder addPurchaseOrder(AddPurchaseOrderReq req) {
        R r = purchaseOrderFeignService.addPurchaseOrder(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()) {
            throw new ErrorDataException(r.getMsg());
        }
        return BeanUtil.toBean(r.getData(), PurchaseOrder.class);
    }


    /**
     * 查询供应商
     *
     * @param req
     * @return
     */
    public Supplier querySupplier(SupplierReq req) {
        R r = supplierFeignService.getOneBySupplierReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询供应商有误");
        } else if (null == r.getData()) {
            return null;
        }
        return BeanUtil.toBean(r.getData(), Supplier.class);
    }


    /**
     * 查询供应商报价单
     *
     * @param req
     * @return
     */
    public OfferOrder queryOfferOrder(OfferOrderReq req) {
        R<OfferOrder> r = offerOrderFeignService.getOneByOfferOrderReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询供应商报价单有误");
        }
        return r.getData();
    }

    /**
     * 查询供应商报价单列表
     *
     * @param req
     * @return
     */
    public List<OfferOrder> queryOfferOrderList(OfferOrderReq req) {
        R<List<OfferOrder>> r = offerOrderFeignService.getOfferOrderList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询供应商报价单有误");
        } else if (null == r.getData()) {
            return new ArrayList<>();
        }
        return r.getData();
    }

    /**
     * 查询采购商
     *
     * @param req
     * @return
     */
    public Buyer queryBuyer(BuyerReq req) {
        R r = buyerFeignService.getOneByBuyerReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询采购商有误");
        } else if (null == r.getData()) {
            return null;
        }
        return BeanUtil.toBean(r.getData(), Buyer.class);
    }

    /**
     * 查询采购单
     *
     * @param req
     * @return
     */
    public BuyOrder queryBuyOrder(BuyOrderReq req) {
        R r = buyOrderFeignService.getOneByBuyOrderReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询采购单有误");
        } else if (null == r.getData()) {
            return null;
        }
        return BeanUtil.toBean(r.getData(), BuyOrder.class);
    }

    /**
     * 查询采购单
     *
     * @param req
     * @return
     */
    public List queryBuyOrderList(BuyOrderReq req) {
        R r = buyOrderFeignService.getBuyOrderList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询采购单有误");
        } else if (null == r.getData()) {
            return null;
        }
        return (List) r.getData();
    }

    /**
     * 查询采购单
     *
     * @param req
     * @return
     */
    public List<BuyOrderDetail> queryBuyOrderDetailList(BuyOrderDetailReq req) {
        R<List<BuyOrderDetail>> r = buyOrderDetailFeignService.getBuyOrderDetailList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询采购单有误");
        } else if (null == r.getData()) {
            return new ArrayList<>();
        }
        return r.getData();
    }

    /**
     * 查询 可退款的退货单  根据pmId/ returnSn
     *
     * @param req
     * @return
     */
    public ReturnOrder fetchRefund(ReturnOrderReq req) {
        R r = returnOrderFeignService.fetchRefund(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询可退款的退货单有误");
        } else if (null == r.getData()) {
            return null;
        }
        return BeanUtil.toBean(r.getData(), ReturnOrder.class);
    }

    /**
     * 查询退货单
     *
     * @param req pmId
     * @return
     */
    public ReturnOrder queryReturnOrder(ReturnOrderReq req) {
        R r = returnOrderFeignService.getOneByReturnOrderReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询退货单有误");
        } else if (null == r.getData()) {
            return null;
        }
        return BeanUtil.toBean(r.getData(), ReturnOrder.class);
    }

    /**
     * 查询退货单明细列表
     *
     * @param req pmId
     * @return
     */
    public List<ReturnOrderDetail> queryReturnOrderDetailList(ReturnOrderDetailReq req) {
        R<List<ReturnOrderDetail>> r = returnOrderDetailFeignService.getReturnOrderDetailList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询退货单有误");
        } else if (null == r.getData()) {
            return new ArrayList<>();
        }
        return r.getData();
    }

    /**
     * 保存或修改图片组图片
     *
     * @param photoGroupDTO
     * @return
     */
    @CacheEvict(value = ScmCacheNameConstant.PHOTO_GROUP_LIST, key = "#photoGroupDTO.groupNum", condition = "#photoGroupDTO.groupNum != null")
    public String savePhotoGroup(PhotoGroupDTO photoGroupDTO) {
        R<PhotoGroupManage> r = photoGroupManageFeignService.savePhotoGroup(photoGroupDTO, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r)) {
            throw new ErrorDataException("保存或修改图片组图片失败");
        } else if (null == r.getData()) {
            return null;
        }
        return r.getData().getGroupNum();
    }

    /**
     * 查询图片组图片
     *
     * @param groupNum
     * @return
     */
    @Cacheable(value = ScmCacheNameConstant.PHOTO_GROUP_LIST, key = "#groupNum", condition = "#groupNum != null")
    public List<PhotoGallery> fetchPhotoGroup(String groupNum) {
        R<PhotoGroupDTO> r = photoGroupManageFeignService.fetchByGroupNum(groupNum, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r)) {
            throw new ErrorDataException("查询图片组图片失败");
        }
        List<PhotoGallery> photoList;
        if (null == r.getData()) {
            photoList = new ArrayList<>(10);
        } else {
            photoList = r.getData().getPhotoList();
        }
        return photoList;
    }

    /**
     * 查询供应订单
     *
     * @param req
     * @return
     */
    public SupplyOrder querySupplyOrder(SupplyOrderReq req) {
        R<SupplyOrder> r = supplyOrderFeignService.getOneBySupplyOrderReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询供应订单失败");
        }
        return r.getData();
    }

    /**
     * 查询供应订单列表
     *
     * @param req
     * @return
     */
    public List<SupplyOrder> querySupplyOrderList(SupplyOrderReq req) {
        R<List<SupplyOrder>> r = supplyOrderFeignService.getSupplyOrderList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询供应订单列表失败");
        } else if (null == r.getData()) {
            return new ArrayList<>();
        }
        return r.getData();
    }

    /**
     * 销售订单查询
     *
     * @param req
     * @return
     */
    public SalesOrder querySalesOrder(SalesOrderReq req) {
        R<SalesOrder> r = salesOrderFeignService.getOneBySalesOrderReq(req, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r)) {
            throw new ErrorDataException("查询销售订单失败");
        }
        return r.getData();
    }

    /**
     * 客户商家获取 没有时创建
     *
     * @param customerSn
     * @return
     */
    public CustomerMerchantDTO fetchCustomerMerchant(String customerSn) {
        CustomerMerchantDTO req = new CustomerMerchantDTO();
        req.setCustomerSn(customerSn);
        R<CustomerMerchantDTO> r = customerMerchantRelationFeignService.fetchCustomerMerchant(req, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r)) {
            throw new ErrorDataException("查询销售订单失败");
        }
        return r.getData();
    }

    // 订单查询

    public OrderInfoDTO fetchBuyOrderInfo(String orderSn) {
        R<OrderInfoDTO> r = buyOrderFeignService.fetchOrderIfo(orderSn, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r) || null == r.getData()) {
            throw new ErrorDataException("查询采购单详情失败");
        }
        return r.getData();
    }

    public OrderInfoDTO fetchSupplyOrderInfo(String orderSn) {
        R<OrderInfoDTO> r = supplyOrderFeignService.fetchOrderIfo(orderSn, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r) || null == r.getData()) {
            throw new ErrorDataException("查询供应单详情失败");
        }
        return r.getData();
    }

    public OrderInfoDTO fetchReturnOrderInfo(String orderSn) {
        R<OrderInfoDTO> r = returnOrderFeignService.fetchOrderIfo(orderSn, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r) || null == r.getData()) {
            throw new ErrorDataException("查询退货单详情失败");
        }
        return r.getData();
    }

    public OrderInfoDTO fetchSalesOrderInfo(String orderSn) {
        R<OrderInfoDTO> r = salesOrderFeignService.fetchOrderIfo(orderSn, SecurityConstants.FROM_IN);
        if (RUtil.isFailed(r) || null == r.getData()) {
            throw new ErrorDataException("查询销售订单详情失败");
        }
        return r.getData();
    }

    /**
     * 查询订单详情
     *
     * @param orderSn
     * @param orderType
     * @return
     */
    public OrderInfoDTO fetchOrderInfo(String orderSn, OrderTypeEnum orderType) {
        OrderInfoDTO orderInfo;
        switch (orderType) {
            case buy:
                orderInfo = fetchBuyOrderInfo(orderSn);
                break;
            case supply:
                orderInfo = fetchSupplyOrderInfo(orderSn);
                break;
            case back:
                orderInfo = fetchReturnOrderInfo(orderSn);
                break;
            case sales:
                orderInfo = fetchSalesOrderInfo(orderSn);
                break;
            default:
                throw new ErrorDataException("订单获取有误");
        }
        return orderInfo;
    }

}
